import os
import time
import micropython
from machine import I2S
from machine import Pin

# ======= I2S CONFIGURATION =======
SCK_PIN = 12
WS_PIN = 14
SD_PIN = 13
I2S_ID = 0
BUFFER_LENGTH_IN_BYTES = 2000

# ======= AUDIO CONFIGURATION =======
WAV_FILE = "music-16k-16bits-mono.wav"
WAV_SAMPLE_SIZE_IN_BITS = 16
FORMAT = I2S.MONO
SAMPLE_RATE_IN_HZ = 11025
# ======= AUDIO CONFIGURATION =======

PLAY = 0
PAUSE = 1
RESUME = 2
STOP = 3


def eof_callback(arg):
    global state
    print("e")
    # state = STOP  # uncomment to stop looping playback


state = PAUSE


# add runtime code here ....
# changing 'state' will affect playback of audio file


class Audio:
    def __init__(self) -> None:
        self.state = STOP

        self.audio_out = I2S(
            I2S_ID,
            sck=Pin(SCK_PIN),
            ws=Pin(WS_PIN),
            sd=Pin(SD_PIN),
            mode=I2S.TX,
            bits=WAV_SAMPLE_SIZE_IN_BITS,
            format=FORMAT,
            rate=SAMPLE_RATE_IN_HZ,
            ibuf=BUFFER_LENGTH_IN_BYTES,
        )

        self.wav = open("esp_toytrain/assets/engine.wav", "rb")
        # advance to first byte of Data section in WAV file
        _ = self.wav.seek(44)

        # allocate a small array of blank samples
        self.silence = bytearray(1000)

        # allocate sample array buffer
        self.wav_samples = bytearray(4096)
        self.wav_samples_mv = memoryview(self.wav_samples)
        self.audio_out.irq(self.i2s_callback)
        _ = self.audio_out.write(self.silence)

    def i2s_callback(self, arg):
        if self.state == PLAY:
            num_read = self.wav.readinto(self.wav_samples_mv)
            # end of WAV file?
            if num_read == 0:
                # end-of-file, advance to first byte of Data section
                pos = self. wav.seek(44)
                num_read = self. wav.readinto(self.wav_samples_mv)
                micropython.schedule(eof_callback, None)
            # else:
            _ = self.audio_out.write(self.wav_samples_mv[:num_read])
        elif self.state == RESUME:
            self.state = PLAY
            _ = self.audio_out.write(self.silence)
        elif self.state == PAUSE:
            _ = self.audio_out.write(self.silence)
        elif self.state == STOP:
            # cleanup
            self.wav.close()
            self.audio_out.deinit()
            print("Done")
        else:
            print("Not a valid state.  State ignored")


print("starting playback for 10s")
state = PLAY
audio = Audio()
audio.state = PLAY
time.sleep(5)
# print("pausing playback for 10s")
audio.state = PAUSE
# time.sleep(10)
# print("resuming playback for 15s")
# state = RESUME
# time.sleep(15)
# print("stopping playback")
# state = STOP
